﻿#region Imports
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using CommonUtilities.Enums;
using CommonUtilities.Events;
using CommonUtilities.Extensions;
using CommonUtilities.Util;
#endregion

namespace CommonUtilities.Controls
{
    /// <summary>
    /// CommonUtilities TextBox control to hold address
    /// (inherited from CommonUtilities.Controls.CUtil_TextBox)
    /// </summary>
    public class CUtil_AddressTextBox : CUtil_TextBox
    {
        #region Declarations
        public new event EventHandler Click;
        public new event KeyEventHandler KeyDown;
        public new event KeyEventHandler KeyUp;
        public new event KeyPressEventHandler KeyPress;
        #endregion

        #region Properties
        /// <summary>
        /// Specifies if the path contains a file name
        /// </summary>
        public bool IsFileName { get; set; }

        /// <summary>
        /// Tooltip of control
        /// </summary>
        public CUtil_InvalidPathTooltip InvalidPathToolTip { get; set; }

        /// <summary>
        /// Characters to ignore for validation
        /// </summary>
        internal List<char> IgnoreKeys { get; private set; }

        /// <summary>
        /// Invalid path characters
        /// </summary>
        internal List<char> InvalidPathChars { get; private set; }
        #endregion

        #region Constructors
        /// <summary>
        /// Default constructor
        /// </summary>
        public CUtil_AddressTextBox()
            : base()
        {
            InvalidPathToolTip = new CUtil_InvalidPathTooltip(this);

            base.Click += new EventHandler(CUtil_AddressTextBox_Click);
            base.KeyDown += new KeyEventHandler(CUtil_AddressTextBox_KeyDown); // new KeyEventHandler(EventList.TextControl_SelectAll);
            base.KeyUp += new KeyEventHandler(CUtil_AddressTextBox_KeyUp);
            base.KeyPress += new KeyPressEventHandler(CUtil_AddressTextBox_KeyPress);

            IgnoreKeys = new List<char>();
            IgnoreKeys.Add('\b');
            IgnoreKeys.Add('\r');
            IgnoreKeys.Add('\n');
            IgnoreKeys.Add('\\');
            IgnoreKeys.Add((char)27); // Escape

            InvalidPathChars = Path.GetInvalidPathChars()
                .Union(Path.GetInvalidFileNameChars())
                .Distinct().Where(c => !IgnoreKeys.Contains(c)).ToList();
        }
        #endregion

        #region Formatting events
        private void CUtil_AddressTextBox_Click(object sender, EventArgs e)
        {
            if (LinkBehaviour)
            {
                string path = this.Text;
                if (Form.ModifierKeys == Keys.Control)
                    if (path.ValidatePath(IsFileName ? ePathValidation.File : ePathValidation.Directory))
                        Utilities.OpenPath(path);
            }

            //enable_hyperlink_or_make_visible // RKD1234

            if (!this.Click.IsNull())
                this.Click(sender, e);
        }

        private void CUtil_AddressTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Form.ModifierKeys == Keys.Control) return;

            if (e.KeyChar == (char)Keys.Back || e.KeyChar == (char)Keys.Delete)
            { e.Handled = false; return; }

            char chrPressed = e.KeyChar;
            char cOnlyOne = ':';

            if (!IsFileName) IgnoreKeys.Add(cOnlyOne);
            else if (IgnoreKeys.Contains(cOnlyOne)) IgnoreKeys.Remove(cOnlyOne);

            e.Handled = IsFileName
                 ? Path.GetInvalidFileNameChars().Contains(chrPressed)
                 : (InvalidPathChars.Contains(chrPressed) || (chrPressed == cOnlyOne && this.Text.Contains(cOnlyOne)));

            if (e.Handled) InvalidPathToolTip.ShowToolTip();
            else InvalidPathToolTip.HideToolTip();

            if (!this.KeyPress.IsNull())
                this.KeyPress(sender, e);
        }

        private void CUtil_AddressTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (LinkBehaviour && Form.ModifierKeys == Keys.Control)
            {
                CUtil_AddressTextBox txt = (CUtil_AddressTextBox)sender;
                txt.Font = new Font(txt.Font.FontFamily, txt.Font.Size, FontStyle.Underline, txt.Font.Unit, txt.Font.GdiCharSet);
                txt.Cursor = Cursors.Hand;

                if (e.KeyCode == Keys.A)
                    EventList.TextControl_SelectAll(sender, e); // Ctrl+A
            }

            if (!this.KeyDown.IsNull())
                this.KeyDown(sender, e);
        }

        private void CUtil_AddressTextBox_KeyUp(object sender, KeyEventArgs e)
        {
            if (LinkBehaviour)
            {
                CUtil_AddressTextBox txt = (CUtil_AddressTextBox)sender;
                txt.Font = new Font(txt.Font.FontFamily, txt.Font.Size, InitialFontStyle, txt.Font.Unit, txt.Font.GdiCharSet);
                txt.Cursor = InitialCursor;
            }

            if (!this.KeyUp.IsNull())
                this.KeyUp(sender, e);
        }
        #endregion

        #region Methods
        public override string ToString()
        {
            return Utilities.ToString(this);
        }
        #endregion
    }
}
